package hy.filter;

import hy.bean.Articles;
import hy.bean.InMessage;
import hy.bean.OutMessage;
import hy.bean.TextOutMessage;
import hy.inf.MessageProcessingHandler;
import hy.util.Tools;
import hy.util.XStreamFactory;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.Properties;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.thoughtworks.xstream.XStream;

/**
 * Servlet Filter implementation class WechatFilter
 */
@WebFilter("/WechatFilter")
public class WechatFilter implements Filter {
	
	private String token = "backspace";
	private String			conf			= "classPath:hywechat.properties";
	private String			defaultHandler	= "hy.handler.DefaultMessageProcessingHandlerImpl";
	private Properties		p;
    /**
     * Default constructor. 
     */
    public WechatFilter() {
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see Filter#destroy()
	 */
	public void destroy() {
		// TODO Auto-generated method stub
	}

	/**
	 * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
	 */
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		HttpServletRequest req = (HttpServletRequest) request;
		HttpServletResponse res = (HttpServletResponse) response;
		String method = req.getMethod();
		String path = req.getServletPath();
		token = path.substring(path.lastIndexOf("/")).substring(1);
	//	System.out.println(token);
		if(token == null){
			res.getWriter().write("error");
			return;
		}
		if(method.equalsIgnoreCase("GET")){
			verify(request, response);
		}
		else {
			server(req, res);
		}
//		doFilter(request, response, chain);
		
	}
	public void server(ServletRequest request, ServletResponse response) throws IOException{
		response.setCharacterEncoding("UTF-8");
		response.setContentType("text/xml");
		OutMessage oms = new OutMessage();
		ServletInputStream in = request.getInputStream();
		// 转换微信post过来的xml内容
		XStream xs = XStreamFactory.init(false);
		xs.alias("xml", InMessage.class);
		String xmlMsg = Tools.inputStream2String(in);

		

		InMessage msg = (InMessage) xs.fromXML(xmlMsg);
		msg.setRequest(request);
		msg.setResponse(response);
		// 获取自定消息处理器，如果自定义处理器则使用默认处理器。
		String handler = p.getProperty("MessageProcessingHandlerImpl");
		if (handler == null)
			handler = defaultHandler;

		try {
			// 加载处理器
			Class<?> clazz = Class.forName(handler);
			MessageProcessingHandler processingHandler = (MessageProcessingHandler) clazz.newInstance();
			// 取得消息类型
			String type = msg.getMsgType();
			Method mt = clazz.getMethod(type + "TypeMsg", InMessage.class);
			oms = (OutMessage) mt.invoke(processingHandler, msg);
			if (oms == null) {
				oms = new TextOutMessage();
				((TextOutMessage) oms).setContent("系统错误1!");
			}
			setMsgInfo(oms,msg);
		} catch (Exception e) {
			
			oms = new TextOutMessage();
			((TextOutMessage) oms).setContent("系统错误2!" + e.toString());
			try {
				setMsgInfo(oms,msg);
			} catch (Exception e1) {
		
			}
		}

		// 把发送发送对象转换为xml输出
		xs = XStreamFactory.init(true);
		xs.alias("xml", oms.getClass());
		xs.alias("item", Articles.class);
		String xml = xs.toXML(oms);

	

		response.getWriter().write(xml);
		
	}
	
	
	private void setMsgInfo(OutMessage oms,InMessage msg) throws Exception {
		// 设置发送信息
		Class<?> outMsg = oms.getClass().getSuperclass();
		Field CreateTime = outMsg.getDeclaredField("CreateTime");
		Field ToUserName = outMsg.getDeclaredField("ToUserName");
		Field FromUserName = outMsg.getDeclaredField("FromUserName");

		ToUserName.setAccessible(true);
		CreateTime.setAccessible(true);
		FromUserName.setAccessible(true);

		CreateTime.set(oms, new Date().getTime());
		ToUserName.set(oms, msg.getFromUserName());
		FromUserName.set(oms, msg.getToUserName());
	}
	
	public void verify(ServletRequest request, ServletResponse response) throws IOException{
		String signature = request.getParameter("signature");// 微信加密签名
		String timestamp = request.getParameter("timestamp");// 时间戳
		String nonce = request.getParameter("nonce");// 随机数
		String echostr = request.getParameter("echostr");//
		// 验证
		if (Tools.checkSignature(token, signature, timestamp, nonce)) {
			response.getWriter().write(echostr);
		}
		
	}

	/**
	 * @see Filter#init(FilterConfig)
	 */
	public void init(FilterConfig fConfig) throws ServletException {
		String cf = fConfig.getInitParameter("conf");
		if (cf != null) {
			conf = cf;
		}
		String classPath = this.getClass().getResource("/").getPath().replaceAll("%20", " ");
		conf = conf.replace("classPath:", classPath);
		p = new Properties();
		File pfile = new File(conf);
		if (pfile.exists()) {
			try {
				p.load(new FileInputStream(pfile));
				System.out.println("mark");
			} catch (FileNotFoundException e) {
			
			} catch (IOException e) {
		
			}
		}
		
		
	}

}
